package org.ekstrabilet.main.gui.tabs;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableCellRenderer;

import org.ekstrabilet.admin.Row;
import org.ekstrabilet.admin.UserTable;
import org.ekstrabilet.main.gui.panes.Panes;
import org.ekstrabilet.user.beans.User;
import org.ekstrabilet.user.logic.UserLogic;

/**
 * Administration tab GUI class.
 *
 */
public class AdminTab {
	
	private JPanel pane;
	private JPanel editorPane;
	private JPanel buttonPane;
	private JScrollPane tablePane;

	//editor pane
	private JLabel lLogin, lName, lSurname, lNewPass, lType;
	private JTextField tfLogin, tfName, tfSurname;
	private JPasswordField pfNewPass;
	private JComboBox cType;
	
	private String[] typeTable = {Panes.GUEST, Panes.SALES, Panes.TECH, Panes.ADMIN};
	
	//button pane
	private JButton bAdd, bEdit, bRemove, bSave, bLoad;
	
	//table pane
	private JTable jTable;
	private UserTable userTable;
	
	//logic
	private List<User> addList, editList, deleteList;
	
	public AdminTab() {
		initPane();
		
		addList = new LinkedList<User>();
		editList = new LinkedList<User>();
		deleteList = new LinkedList<User>();
		
		load();
	}
	
	private void initPane() {
		initEditorPane();
		initButtonPane();
		initTablePane();
		pane = new JPanel();
		pane.setLayout(new GridBagLayout());
		GridBagConstraints c = new GridBagConstraints();
		c.fill = GridBagConstraints.HORIZONTAL;
		c.insets = new Insets(20,30,20,30);

		//mid
		c.weightx = 300;
		c.weightx = 150;
		c.gridx = 1;
		c.gridy = 0;
		pane.add(editorPane, c);
		c.gridx = 1;
		c.gridy = 1;
		pane.add(buttonPane, c);
		
		//sides
		c.weightx = 300;
		c.gridheight = 2;
		c.gridx = 0;
		c.gridy = 0;
		pane.add(new JPanel(), c);
		c.gridx = 2;
		c.gridy = 0;
		pane.add(new JPanel(), c);
		
		//table
		c.fill = GridBagConstraints.BOTH;
		c.weighty = 500;
		c.gridx = 0;
		c.gridy = 2;
		c.gridwidth = 3;
		c.gridheight = 1;
		pane.add(tablePane, c);
	}
	
	private void initEditorPane() {
		lLogin = new JLabel("Login:  ");
		lName = new JLabel("Name:  ");
		lSurname = new JLabel("Surname:  ");
		lNewPass = new JLabel("New password:  ");
		lType = new JLabel("User type:  ");
		
		tfLogin = new JTextField();
		tfName = new JTextField();
		tfSurname = new JTextField();
		
		pfNewPass = new JPasswordField();
		
		cType = new JComboBox(typeTable);
		
		editorPane = new JPanel();
		editorPane.setLayout(new GridLayout(6, 2, 8, 8));
		editorPane.add(lLogin);
		editorPane.add(tfLogin);
		editorPane.add(lName);
		editorPane.add(tfName);
		editorPane.add(lSurname);
		editorPane.add(tfSurname);
		editorPane.add(lType);
		editorPane.add(cType);
		editorPane.add(new JSeparator());
		editorPane.add(new JSeparator());
		editorPane.add(lNewPass);
		editorPane.add(pfNewPass);
	}
	
	private void initButtonPane() {
		bAdd = new JButton("add");
		bEdit = new JButton("edit");
		bRemove = new JButton("remove");
		bSave = new JButton("save");
		bLoad = new JButton("load");
		
		bAdd.addActionListener(new AddListener());
		bEdit.addActionListener(new EditListener());
		bRemove.addActionListener(new RemoveListener());
		bSave.addActionListener(new SaveListener());
		bLoad.addActionListener(new LoadListener());
		
		buttonPane = new JPanel();
		buttonPane.setLayout(new GridLayout(1, 5, 8, 8));
		buttonPane.add(bAdd);
		buttonPane.add(bEdit);
		buttonPane.add(bRemove);
		buttonPane.add(bSave);
		buttonPane.add(bLoad);
	}
	
	private void initTablePane() {
	    DefaultTableCellRenderer dtcr = new DefaultTableCellRenderer();
        dtcr.setHorizontalAlignment(SwingConstants.CENTER);
        
        userTable = new UserTable();
        
	    jTable = new JTable(userTable);
	    jTable.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
		
	    for(int i = 0; i < jTable.getColumnCount(); i++) {
			jTable.getColumnModel().getColumn(i).setCellRenderer(dtcr);
		}
		
        jTable.setFillsViewportHeight(true);
	    tablePane = new JScrollPane(jTable);
	    tablePane.revalidate();
	    tablePane.repaint();
	}
	
	public JPanel getTab() {
		return pane;
	}

	class AddListener implements ActionListener {
		
		@Override
		public void actionPerformed(ActionEvent e) {
			if(pfNewPass.getText() == null || pfNewPass.getText().length() == 0) {
				JOptionPane.showMessageDialog(pane, "Add failed. New user must have password.");
				return;
			}
			Row row = new Row();
			row.setLogin(tfLogin.getText());
			row.setName(tfName.getText());
			row.setSurname(tfSurname.getText());
			row.setType((String)cType.getItemAt(cType.getSelectedIndex()));
			if(!userTable.addRow(row)) {
				JOptionPane.showMessageDialog(pane, "Add failed. User with such login already exists.");
			} else {
				addList.add(UserLogic.initUser(row, pfNewPass.getText()));
				tablePane.revalidate();
				tablePane.repaint();
			}
		}	
	}
	
	class EditListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			Row row = new Row();
			row.setLogin(tfLogin.getText());
			row.setName(tfName.getText());
			row.setSurname(tfSurname.getText());
			row.setType((String)cType.getItemAt(cType.getSelectedIndex()));
			if(!userTable.editRow(row)) {
				JOptionPane.showMessageDialog(pane, "Edit failed. User with such login does not exist.");
			} else {
				editList.add(UserLogic.initUser(row, pfNewPass.getText()));
				tablePane.revalidate();
				tablePane.repaint();
			}
		}
	}
	
	class RemoveListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			Row row = new Row();
			row.setLogin(tfLogin.getText());
			if(!userTable.delRow(row)) {
				JOptionPane.showMessageDialog(pane, "Remove failed. User with such login does not exist.");
			} else {
				deleteList.add(UserLogic.initUser(row, null));
				tablePane.revalidate();
				tablePane.repaint();
			}
		}	
	}
	
	class SaveListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			UserLogic ul = UserLogic.getInstance();
			Iterator<User> it = deleteList.iterator();
			while(it.hasNext()) {
				ul.delete(it.next());
			}
			it = addList.iterator();
			while(it.hasNext()) {
				ul.add(it.next());
			}
			it = editList.iterator();
			while(it.hasNext()) {
				ul.update(it.next());
			}
			addList.clear();
			editList.clear();
			deleteList.clear();
		}	
	}
	
	class LoadListener implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			userTable.clear();
			load();
			tablePane.revalidate();
			tablePane.repaint();
		}	
	}
	
	private void load() {
		List<User> list = UserLogic.getInstance().getUsers();
		Iterator<User> it = list.iterator();
		while(it.hasNext()) {
			User u = it.next();
			Row row = new Row(u.getLogin(), u.getName(), u.getSname(), u.getType());
			userTable.addRow(row);
		}
	}
}